package com.neo.tiny.business.queue.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.neo.tiny.business.queue.api.TicketOrderApi;
import com.neo.tiny.business.queue.api.vo.call.ListTicketForCallRes;
import com.neo.tiny.business.queue.client.service.CallTicketOrderService;
import com.neo.tiny.business.queue.enums.TicketStatusEnum;
import com.neo.tiny.service.RedisService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @Description:
 * @Author: yqz
 * @CreateDate: 2022/10/30 11:38
 */
@Slf4j
@Service
@AllArgsConstructor
public class CallTicketOrderServiceImpl implements CallTicketOrderService {

    private final TicketOrderApi ticketOrderApi;

    private final RedisService redisService;


    @Override
    public List<ListTicketForCallRes> listTicketForCallByWindowId(Long windowId) {

        List<ListTicketForCallRes> forCallResList = ticketOrderApi.listTicketForCallByWindowId(windowId,
                Arrays.asList(TicketStatusEnum.TICKET_NO.getStatus(), TicketStatusEnum.CALL_TICKET.getStatus()));
        log.info("窗口：{}，查询待叫号列表：{}", windowId, JSONUtil.toJsonStr(forCallResList));
        return forCallResList;
    }

    @Override
    public Boolean call(Long orderId, Long windowId, Integer ticketStatus) {

        Assert.isTrue(!Objects.isNull(orderId) || !Objects.isNull(windowId), "取号订单id或窗口id不能为空");

        TicketStatusEnum match = TicketStatusEnum.match(ticketStatus);
        Assert.isTrue(BeanUtil.isNotEmpty(match), "不支持的呼叫状态");

        try {
            // todo 加锁
            Boolean lock = redisService.getLock(orderId.toString(), windowId.toString(), 1L);
            if (lock) {
                ListTicketForCallRes call = ticketOrderApi.call(orderId, windowId, ticketStatus);
                log.info("窗口：{}，叫号成功：{}", windowId, orderId);
                return true;
            } else {
                return false;
            }
        } finally {
            Long releaseLock = redisService.releaseLock(orderId.toString(), windowId.toString());
            log.info("释放窗口：{}，订单：{},分布式锁：{}", windowId, orderId, releaseLock);
        }

    }
}
